package com.utils.httpclient;

import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

/**
 * HTTPCLIENT BEAN
 *
 * @author JIANGLONG
 */

public class HttpClientBean {

    private String url;
    private Map<String, String> params;
    private String encode = "UTF-8";
    private ContentTypeEnum contentType = ContentTypeEnum.APPOLICATION_X_WWW_FORM_URLENCODED;

    public HttpClientBean(String url) {
        this(url, null, null, null);
    }

    public HttpClientBean(String url, Map<String, String> params) {
        this(url, params, null, null);
    }

    public HttpClientBean(String url, Map<String, String> params, String encode) {
        this(url, params, encode, null);
    }

    public HttpClientBean(String url, String encode) {
        this(url, null, encode, null);
    }

    public HttpClientBean(String url, Map<String, String> params, String encode, ContentTypeEnum contentType) {
        this.url = url;
        this.params = params;
        if (null != encode && !"".equals(encode)) {
            this.encode = encode;
        }
        if (null != contentType) {
            this.contentType = contentType;
        }
    }

    /**
     * GET请求
     *
     * @return
     */
    public String doGet() throws Exception {
        String result = null;
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        try {
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000).setSocketTimeout(5000).setRedirectsEnabled(true).build();
            httpClient = HttpClientPoolManagerBuilder.build().buildHttpClient(requestConfig);
            url = HttpParamsBuilder.getParamsBuilder(url, params, encode);
            HttpGet httpGet = new HttpGet(url);
            httpGet.setConfig(requestConfig);
            httpResponse = httpClient.execute(httpGet);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                result = EntityUtils.toString(httpResponse.getEntity(), encode);
            } else {
                throw new Exception("error statusCode:" + httpResponse.getStatusLine().getStatusCode() + "");
            }
        } finally {
            release(httpResponse, null);
        }
        return result;
    }

    /**
     * POST請求
     *
     * @return
     */
    public String doPost() throws Exception {
        String result = null;
        CloseableHttpResponse httpResponse = null;
        CloseableHttpClient httpClient = null;
        try {
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000).setSocketTimeout(5000).setRedirectsEnabled(true).build();
            httpClient = HttpClientPoolManagerBuilder.build().buildHttpClient(requestConfig);
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            httpPost.setHeader("Content-type", contentType.getContentType());
            switch (contentType) {
                case APPOLICATION_JSON:
                    httpPost.setEntity(new StringEntity(HttpParamsBuilder.jsonParamsBuilder(params), encode));
                    break;
                case APPOLICATION_X_WWW_FORM_URLENCODED:
                    httpPost.setEntity(new UrlEncodedFormEntity(HttpParamsBuilder.formParamsBuilder(params), encode));
                    break;
                case APPOLICATION_XML:
                    httpPost.setEntity(new StringEntity(HttpParamsBuilder.mapToXmlBuilder(params), encode));
                    break;
                default:
                    httpPost.setEntity(new UrlEncodedFormEntity(HttpParamsBuilder.formParamsBuilder(params), encode));
                    break;
            }
            httpResponse = httpClient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = httpResponse.getEntity();
                if (entity != null) {
                    result = EntityUtils.toString(entity, encode);
                }
                EntityUtils.consume(entity);
            } else {
                throw new Exception("error statusCode:" + httpResponse.getStatusLine().getStatusCode() + "");
            }
        } finally {
            release(httpResponse, null);
        }
        return result;
    }


    /**
     * 获取流
     */
    public byte[]  doPostReturnInputStream()throws Exception{
        byte[]  result = null;
        CloseableHttpResponse httpResponse = null;
        CloseableHttpClient httpClient = null;
        try {
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000).setSocketTimeout(5000).setRedirectsEnabled(true).build();
            httpClient = HttpClientPoolManagerBuilder.build().buildHttpClient(requestConfig);
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            httpPost.setHeader("Content-type", contentType.getContentType());
            switch (contentType) {
                case APPOLICATION_JSON:
                    httpPost.setEntity(new StringEntity(HttpParamsBuilder.jsonParamsBuilder(params), encode));
                    break;
                case APPOLICATION_X_WWW_FORM_URLENCODED:
                    httpPost.setEntity(new UrlEncodedFormEntity(HttpParamsBuilder.formParamsBuilder(params), encode));
                    break;
                case APPOLICATION_XML:
                    httpPost.setEntity(new StringEntity(HttpParamsBuilder.mapToXmlBuilder(params), encode));
                    break;
                default:
                    httpPost.setEntity(new UrlEncodedFormEntity(HttpParamsBuilder.formParamsBuilder(params), encode));
                    break;
            }
            httpResponse = httpClient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = httpResponse.getEntity();
                if (entity != null) {
                    result = EntityUtils.toByteArray(entity);
                }
                EntityUtils.consume(entity);
            } else {
                throw new Exception("error statusCode:" + httpResponse.getStatusLine().getStatusCode() + "");
            }
        } finally {
            release(httpResponse, null);
        }
        return  result;
    }



    /**
     * PUT請求
     *
     * @return
     */
    public String doPut() throws Exception {
        String result = null;
        CloseableHttpResponse httpResponse = null;
        CloseableHttpClient httpClient = null;
        try {
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000).setSocketTimeout(5000).setRedirectsEnabled(true).build();
            httpClient = HttpClientPoolManagerBuilder.build().buildHttpClient(requestConfig);
            HttpPut httpPut = new HttpPut(url);
            httpPut.setConfig(requestConfig);
            httpPut.setHeader("Content-type", contentType.getContentType());
            switch (contentType) {
                case APPOLICATION_JSON:
                    httpPut.setEntity(new StringEntity(HttpParamsBuilder.jsonParamsBuilder(params), encode));
                    break;
                case APPOLICATION_X_WWW_FORM_URLENCODED:
                    httpPut.setEntity(new UrlEncodedFormEntity(HttpParamsBuilder.formParamsBuilder(params), encode));
                    break;
                default:
                    httpPut.setEntity(new UrlEncodedFormEntity(HttpParamsBuilder.formParamsBuilder(params), encode));
                    break;
            }
            httpResponse = httpClient.execute(httpPut);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = httpResponse.getEntity();
                if (entity != null) {
                    result = EntityUtils.toString(entity, encode);
                }
                EntityUtils.consume(entity);
            } else {
                throw new Exception("error statusCode:" + httpResponse.getStatusLine().getStatusCode() + "");
            }
        } finally {
            release(httpResponse, null);
        }
        return result;
    }

    /**
     * DELETE請求
     *
     * @return
     */
    public String doDelete() throws Exception {
        String result = null;
        CloseableHttpResponse httpResponse = null;
        CloseableHttpClient httpClient = null;
        try {
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000).setSocketTimeout(5000).setRedirectsEnabled(true).build();
            httpClient = HttpClientPoolManagerBuilder.build().buildHttpClient(requestConfig);
            HttpDeleteWithBody httpDelete = new HttpDeleteWithBody(url);
            httpDelete.setConfig(requestConfig);
            httpDelete.setHeader("Content-type", contentType.getContentType());
            switch (contentType) {
                case APPOLICATION_JSON:
                    httpDelete.setEntity(new StringEntity(HttpParamsBuilder.jsonParamsBuilder(params), encode));
                    break;
                case APPOLICATION_X_WWW_FORM_URLENCODED:
                    httpDelete.setEntity(new UrlEncodedFormEntity(HttpParamsBuilder.formParamsBuilder(params), encode));
                    break;
                default:
                    httpDelete.setEntity(new UrlEncodedFormEntity(HttpParamsBuilder.formParamsBuilder(params), encode));
                    break;
            }
            httpResponse = httpClient.execute(httpDelete);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = httpResponse.getEntity();
                if (entity != null) {
                    result = EntityUtils.toString(entity, encode);
                }
                EntityUtils.consume(entity);
            } else {
                throw new Exception("error statusCode:" + httpResponse.getStatusLine().getStatusCode() + "");
            }
        } finally {
            release(httpResponse, null);
        }
        return result;
    }

    /**
     * 资源回收
     *
     * @param httpClient
     */
    private void release(CloseableHttpResponse httpResponse, CloseableHttpClient httpClient) {
        try {
            if (null != httpResponse) {
                httpResponse.close();
            }
            if (null != httpClient) {
                httpClient.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
